// 这里写路由守卫的代码
// console.log(123)//测试import的执行功能
import router from '@/router'
import store from '@/store'
import asyncRoutes from './router/asyncRoutes'
const whiteList = ['/login', '/404'] // 白名单，没有token也能访问的页面

// 获取一级路由权限标识
function getFirstRoutePerms (perm) {
  // perm = [
  //   'park:enterprise:list',
  //   'park:enterprise:query',
  //   'park:enterprise:add_edit',
  //   'parking:rule:list',
  //   'parking:rule:add_edit'
  // ]//测试数据
  const first = perm.map(function (ele) {
    return ele.split(':')[0]
  })
  // new Set()无法存储重复数据，能够去重，但返回的是个伪数组
  return [...new Set(first)] // 这种写法可以转成数组
}
// 获取二级路由权限标识
function getSecondRoutePerms (perm) {
  // perm = [
  //   'park:enterprise:list',
  //   'park:enterprise:query',
  //   'park:enterprise:add_edit',
  //   'parking:rule:list',
  //   'parking:rule:add_edit'
  // ] // 测试数据
  const second = perm.map(function (ele) {
    return `${ele.split(':')[0]}:${ele.split(':')[1]}`
  })
  // new Set()无法存储重复数据，能够去重，但返回的是个伪数组
  return Array.from(new Set(second)) // 这种写法可以转成数组
}
// 根据一级路由标识、二级路由标识和动态路由进行筛选
function getRoutes (firstRoutePerms, secondRoutePerms, asyncRoutes) {
  // 由于管理员的权限标识是['*:*:*']，无法正常匹配筛选，所以需要优先特殊处理，否则什么都看不到
  if (firstRoutePerms.includes('*')) return asyncRoutes
  // 其余角色
  const firstRoutes = asyncRoutes.filter(function (ele) {
    return firstRoutePerms.includes(ele.permission)
  })
  console.log('筛完一级路由', firstRoutes)
  const secondRoutes = firstRoutes.map(function (item) {
    return {
      ...item,
      // children是个数组，筛出children里应该保留的项，覆写原来的children
      children: item.children.filter(function (child) {
        return secondRoutePerms.includes(child.permission)
      })
    }
  })
  console.log('筛完二级路由', secondRoutes)
  return secondRoutes
}

router.beforeEach(async (to, from, next) => {
  // console.log(to)
  // console.log(from)
  // console.log(next)
  const token = store.state.user.token // 不能写成this.store，在vue组件里this指向vue实例，但在js里不好说
  if (token) {
    if (to.path === '/login') {
      next('/')
    } else {
      // 不去登录页面
      next()
      // 在路由守卫这里调用获取登录角色权限的接口
      // 也可以在登录操作以后调用，但这样的话查看更新后的角色权限就必须重新登录以调用接口
      // 如果在路由守卫这里调用的话，只需要刷新页面就能再次调用接口来查看更新后的角色权限了，更方便合理
      // store.dispatch('menu/getLoginUserRight')
      // console.log(store.state.menu.permissions)//不知道为什么，这种方式输出失败
      // const perm = store.state.menu.permissions
      const perm = await store.dispatch('menu/getLoginUserRight')
      console.log(perm)
      // 根据角色权限标识perm，筛选出对应的一级路由标识
      const firstRoutePerms = getFirstRoutePerms(perm)
      console.log('一级路由标识', firstRoutePerms)
      // 根据角色权限标识perm，筛选出对应的二级路由标识
      const secondRoutePerms = getSecondRoutePerms(perm)
      console.log('二级路由标识', secondRoutePerms)
      // 根据一级路由标识、二级路由标识和动态路由进行筛选
      const routes = getRoutes(firstRoutePerms, secondRoutePerms, asyncRoutes)
      console.log('筛选后的动态路由', routes)
      // 把筛选后的路由展示在左侧
      routes.forEach(item => {
        router.addRoute(item) // router.addRoute方法：添加一条新路由规则（该方法只能一条一条添加）
      })
      // 此时已经可以访问跳转相关页面了，但左侧菜单仍然没有渲染出来
      // 因为左侧菜单的渲染是通过this.$router.options.routes获取路由规则的，该方式不是响应式的，只能获取创建路由对象时传入的路由规则，后续通过addRoute添加的路由是获取不到的
      // 解决方法：放弃使用this.$router.options.routes来渲染页面，将路由规则存入vuex，改为使用vuex来渲染页面
      store.commit('menu/setMenuList', routes)
    }
  } else {
    // 没有token
    if (whiteList.includes(to.path)) {
      // includes是字符串和数组的方法
      next()
    } else {
      next('/login')
    }
  }
})
